/**
 * 省市街区级连组件
 * 公共组件
 */
import { Cascader as AntdCascader } from 'antd';
import * as React from 'react';
import { clone } from 'ramda';
import requests from '@/utils/request';
interface Props {
  onChange?: Function;
  level?: string | number;
  disabled?: boolean;
  selectRecord?: boolean;
  [index: string]: any;
}
interface State {
  options: any[];
  value: Array<string> | Array<number>;
  selectedValue: any;
  lock: any;
  changeOnSelect?: boolean;
}
class RegionCascader extends React.Component<Props, State> {
  static defaultProps = {
    selectRecord: false,
    changeOnSelect: true
  };
  constructor(props) {
    super(props);
    this.state = {
      options: [], //省市区数据
      value: null,
      selectedValue: '',
      lock: true
    };
  }
  findChildrenById = (code: number | string) => {
    return requests(`/yst-system/com/area/pid/${code}`, {
      method: 'get'
    });
  };
  componentDidMount() {
    const { value } = this.props;
    this.getFirstOptions(value, () => {
      this.setState({
        value
      });
    });
  }
  // componentWillReceiveProps(nextProps, prevState) {
  componentDidUpdate(nextProps, prevState) {
    const { value } = nextProps;

    if (
      !!this.props.value &&
      JSON.stringify(this.props.value) !== JSON.stringify(value) &&
      this.state.lock
    ) {
      this.getFirstOptions(this.props.value, () => {
        this.setState({
          value: this.props.value
        });
      });
    }
  }
  checkDataLevel = (data: Array<unknown>, level: number) => {
    if (level && data.length > level) {
      return data.slice(0, level);
    }
    return data;
  };
  /**
   *getFirstOptions
   * @param value
   * @param callBack
   * @returns
   */
  getFirstOptions = async (value, callBack?: Function) => {
    const { success = false, data = [] } = await this.findChildrenById(0);

    if (success) {
      if (value) {
        let options: any = data;
        for (let index = 0; index < value.length - 1; index++) {
          if (index > 2) {
            return;
          }
          let setData = options.filter((item) => {
            if (!!value[index]) {
              if (typeof value[index] === 'object') {
                return value[index].value === item.areaCode;
              } else {
                return value[index] === item.areaCode;
              }
            } else {
              return false;
            }
          });
          if (!!setData && setData?.length > 0) {
            options = await this.getData(setData);
          }
        }
      }
      this.setState(
        {
          options: data
        },
        () => {
          if (callBack) {
            callBack();
          }
        }
      );
    }
  };

  /**
   * 动态加载选项
   * @param selectedOptions
   * @returns
   */
  getData = async (selectedOptions) => {
    return new Promise(async (resolve, reject) => {
      const { level } = this.props;
      const targetOption = selectedOptions[selectedOptions.length - 1];
      targetOption.loading = true;
      const { data } = await this.findChildrenById(targetOption.areaCode);
      targetOption.loading = false;
      targetOption.children =
        level && Number(targetOption.areaLevel) === Number(level) - 1
          ? data.map((v) => {
            return { ...v, isLeaf: true };
          })
          : data;
      const { options } = this.state;
      this.setState(
        {
          options: clone(options)
        },
        () => {
          resolve(targetOption.children);
        }
      );
    });
  };

  /**
   * react生命周期
   *传入的props映射到state上面
   * @param param0
   * @param param1
   * @returns
   */
  static getDerivedStateFromProps({ value, selectRecord }, { selectedValue }) {
    if (selectRecord) {
      let newValue;
      newValue = value && value.map((item) => item.value);
      if (newValue !== selectedValue) {
        return {
          selectedValue: Array.isArray(newValue) && newValue?.filter((v) => !!v)
        };
      }
      return null;
    } else {
      if (value !== selectedValue) {
        return {
          selectedValue: Array.isArray(value) && value?.filter((v) => !!v)
        };
      }
      return null;
    }
  }

  /**
   * 选择完成后的回调
   * @param value
   * @param selectedOptions
   */
  onChange = (value, selectedOptions) => {
    if (this.props.selectRecord) {
      const record = selectedOptions.map((item) => ({
        label: item.areaName,
        value: item.areaCode
      }));
      if (this.props.onChange) {
        this.props.onChange(record, selectedOptions);
      }
    } else {
      if (this.props.onChange) {
        this.props.onChange(value, selectedOptions);
      }
    }
  };
  render() {
    const { options, selectedValue } = this.state;
    return (
      <AntdCascader
        value={selectedValue}
        options={options}
        loadData={this.getData}
        onChange={this.onChange}
        changeOnSelect={this.props.changeOnSelect}
        onPopupVisibleChange={(e) => {
          this.setState({
            lock: !e
          });
        }}
        disabled={this.props.disabled}
        fieldNames={{ label: 'areaName', value: 'areaCode' }}
      />
    );
  }
}
export default RegionCascader;
